$(function() {

    setEdgeColor = function(edge, color) {
        var style = {stroke: color};
        jQuery.extend(edge.style, style);
        edge.connection.fg.animate({stroke: color}, 1000);
    };

    setEdgeLabel = function(edge, label) {
        if (edge.connection.label) {
            edge.connection.label.attr({'text': label});
        }
    };

    setEdgeWeight = function(edge, weight) {
        edge.weight = weight;
        setEdgeLabel(edge, weight);
    };

    getEdgeWeight = function(edge) {
        return edge.weight;
    };


    var code = "";

//    $("#saveAlg").click(function() {
//        var name = prompt("Podaj nazwę algorytmu:");
//        if (name) {
//            if ($("#useralg").length > 0) {
//                $("#useralg")
//            } else {
//                $('#algType').append(
//                        $("<option></option>").attr("id","useralg").attr("value", "user").text(name)
//                        );
//            }
//        }
//    });

    $("#codeClearer").click(function() {
        code = "";
        $("#code").html("");
    });

    $("#addInstr").click(function() {
        var instr;
        var proper = true;
        var codeLine;
        var instrType = $('#instrType').val();
        switch (instrType) {
            case 'an':
                var id = prompt("Podaj id wierzchołka:");
                proper = isProperNodeId(id);
                if (proper) {
                    instr = "animuj wierzchołek " + id;
                    codeLine = "an." + id + ";";
                }
                break;
            case 'ae':
                var startId = prompt("Podaj id wierzchołka początkowego:");
                proper = isProperNodeId(startId);
                if (proper) {
                    var endId = prompt("Podaj id wierzchołka końcowego:");
                    proper = isProperNodeId(endId);
                    if (proper) {
                        instr = "animuj krawędź " + startId + "-" + endId;
                        codeLine = "ae." + startId + "." + endId + ";";
                    }
                }
                break;
        }
        if (proper) {
            code += codeLine;
            $("#code").append(instr + "<br/>");
            $('#code').animate({scrollTop: $('#code').prop("scrollHeight")}, 500);
        }
    });

    isProperNodeId = function(id) {
        if (id === null) {
            return false;
        } else if (!g.nodes[id]) {
            alert("Nieznany wierzchołek.");
            return false;
        }
        return true;
    };


    $('#prepare').click(function() {
        if (active) {
            setControlsInactive();
            clearPreviousAnimations();
            log("---Animacja przygotowana");
            animations.reset();
            var algType = $('#algType').val();
            switch (algType) {
                case 'bfs':
                    bfs();
                    break;
                case 'dfs':
                    dfs();
                    break;
                case 'flow':
                    flow();
                    break;
                case 'user':
                    custom();
                    break;
            }
        }
    });

    custom = function() {
        for (var id in g.nodes) {
            g.nodes[id].shape[0].animate({'fill': "#ffffff"}, getTempo());
        }
        var instr = code.split(";");
        for (var i in instr) {
            var ins = instr[i];
            if (ins) {
                ins = ins.split(".");
                var type = ins[0];
                if (type === "an") {
                    var id = ins[1];
                    addNodeAnim(id);
                }
                if (type === "ae") {
                    var startId = ins[1];
                    var endId = ins[2];
                    addEdgeAnim(startId, endId);
                }
            }
        }
    };

    addNodeAnim = function(id) {
        var node = g.nodes[id];
        if (node) {
            animations.push(function() {
                g.nodes[id].shape[0].animate({'fill': "#000000"}, getTempo(), function() {
                    callbackAnim();
                });
            });
        }
    };

    addEdgeAnim = function(startId, endId) {
        var edge = g.getEdge(startId, endId);
        if (!edge && !directed) {
            edge = g.getEdge(endId, startId);
        }
        if (edge) {
            animations.push(function() {
                var color = "#f00";
                var style = {stroke: color};
                edge.connection.fg.animate(style, getTempo(), function() {
                    callbackAnim();
                });
            });
        }
    }

    clearPreviousAnimations = function() {
        for (var id in g.nodes) {
            g.nodes[id].shape[0].animate({'fill': Raphael.getColor()}, 100);
            g.nodes[id].visited = 0;
        }
        for (var i in g.edges) {
            var edge = g.edges[i];
            var color = "#bfa";
            var style = {stroke: color};
            edge.connection.fg.animate(style, 100);
        }
    };

    $("#play").click(function() {
        stepped = false;
        animations.next();
    });

    $("#pause").click(function() {
        stepped = true;
    });

    $("#nextStep").click(function() {
        if (stepped) {
            animations.next();
        }
    });

    $("#stop").click(function() {
        stepped = true;
        setControlsActive();
        addLog("---Animacja zakończona przez użytkownika");
    });

    setControlsInactive = function() {
        mode = "";
        active = false;
        $("button").attr('disabled', "disabled");
        $(".player").removeAttr('disabled');
    };

    setControlsActive = function() {
        mode = "drag";
        active = true;
        $("button").removeAttr('disabled');
        $(".player").attr('disabled', "disabled");
    };

    isUndefined = function(variable) {
        return typeof variable === "undefined";
    };

    redraw = function() {
        layouter.layout();
        renderer.draw();
        tempLine = null;
    };

    setCookie = function(name, value, days) {
        var expires;
        if (days) {
            var date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            expires = "; expires=" + date.toGMTString();
        } else {
            expires = "";
        }
        document.cookie = escape(name) + "=" + escape(value) + expires + "; path=/";
    };

    getCookie = function(name) {
        var nameEQ = escape(name) + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) === ' ')
                c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) === 0)
                return unescape(c.substring(nameEQ.length, c.length));
        }
        return null;
    };

    delCookie = function(name) {
        setCookie(name, "", -1);
    };

    $("#graphRemover").click(function() {
        var confirmed = confirm("Czy na pewno usunąć zapisany graf?");
        if (confirmed) {
            var name = $('#graphName').val();
            if (name != "g-1" && name != "g-2" && name != "g-3" && name != "g-4") {
                delCookie(name);
                delete graphs[name];
                $("option#" + name).remove();
            } else {
                alert("Nie można usunąć predefiniowanego grafu.");
            }
        }

    });

    $("#graphSaver").click(function() {
        var graphName = prompt("Podaj nazwę zapisywanego grafu:");
        graphName = filterName(graphName);
        var confirmed = true;
        if (graphs[graphName]) {
            confirmed = confirm("Czy na pewno chcesz nadpisać graf: " + graphName + "?");
        }
        if (graphName && confirmed) {
            var graphSave = getGraphSave();
            setCookie(graphName, graphSave);
            graphs[graphName] = graphSave;
            if ($("option#" + graphName).length == 0) {
                $('#graphName').append(
                        $("<option></option>").attr("id", graphName).attr("value", graphName).text(graphName)
                        );
                var names = getCookie("graphNames");
                setCookie("graphNames", names + ";" + graphName);
            }
            log("Zapisano graf w ciasteczkach przeglądarki.");
        } else {
            log("Anulowano zapis grafu.");
        }
    });

    getGraphSave = function() {
        var s = "";
        if (directed) {
            s += "1|";
        } else {
            s += "0|";
        }
        for (var id in g.nodes) {
            s += id + ";";
        }
        s += "|";
        for (var i in g.edges) {
            var edge = g.edges[i];
            var startId = edge.source.id;
            var endId = edge.target.id;
            var weight = edge.style.label || "";
            s += startId + ":" + endId + ":" + weight + ";";
        }
        return s;
    };

    var graphs = {};
    if (getCookie("graphNames") === null) {
        setCookie("graphNames", "");
    }
    var graphNames = getCookie("graphNames");
    loadGraphOptions = function() {
        if (graphNames) {
            graphNames = graphNames.split(";");
            for (var i in graphNames) {
                var name = graphNames[i];
                var cookie = getCookie(name);
                if (name && cookie && !graphs[name]) {
                    graphs[name] = cookie;
                    $('#graphName').append(
                            $("<option></option>").attr("id", name).attr("value", name).text(name)
                            );
                }
            }
        }
    };
    loadGraphOptions();

    loadGraph = function(graphId) {
        var graphSave = graphs[graphId];
        graphSave = graphSave.split("|");
        var graphDirected = graphSave[0] == 1 ? true : false;
        var graphNodes = graphSave[1];
        var graphEdges = graphSave[2];
        if (graphDirected) {
            setDirected();
        } else {
            setUndirected();
        }
        graphNodes = graphNodes.split(";");
        graphNodes.pop();
        for (var id in graphNodes) {
            var nodeId = graphNodes[id];
            g.addNode(nodeId);
        }
        graphEdges = graphEdges.split(";");
        graphEdges.pop();
        for (var i in graphEdges) {
            var edge = graphEdges[i];
            edge = edge.split(":");
            var startId = edge[0];
            var endId = edge[1];
            var label = edge[2];
            if (label) {
                addEdge(startId, endId, label);
            } else {
                addEdge(startId, endId);
            }
        }
    };

    addEdge = function(start, end, weight) {
        var options = {stroke: "#bfa", directed: directed};
        if (weight != undefined) {
            weight = filterWeight(weight);
            options.label = weight;
        }
        var result = g.addEdge(start, end, options);
        return result;
    };

    edgeClick = function() {
        if (mode === "delete") {
            var start = this.source;
            var end = this.target;
            g.removeEdge(start, end);
            log("Usunięto krawędź między wierzchołkami: " + start + " i " + end)
        }
    };

    dfs = function() {
        animations.reset();
        for (var id in g.nodes) {
            g.nodes[id].shape[0].animate({'fill': "#ffffff"}, getTempo());
            g.nodes[id].visited = false;
        }
        var startId = $("#startId").val();
        visit(startId);
    };

    visit = function(id, idOfPrevious) {

        var edge;
        if (idOfPrevious) {
            edge = g.getEdge(idOfPrevious, id);
            if (!edge) {
                edge = g.getEdge(id, idOfPrevious);
            }
        }

        addDfsAnim(id, edge);

        g.nodes[id].visited = true;

        for (var i in g.nodes[id].edges) {
            var edge = g.nodes[id].edges[i];
            var idSasiada = edge.target.id;
            if (idSasiada === id && !directed) {
                idSasiada = edge.source.id;
            }
            if (!g.nodes[idSasiada].visited) {
                visit(idSasiada, id);
            }
        }
    };

    addDfsAnim = function(id, edge) {
        if (edge) {
            animations.push(function() {
                addLog("Odwiedzam: " + id);
                var color = "#f00";
                var style = {stroke: color};
                edge.connection.fg.animate(style, getTempo());
                g.nodes[id].shape[0].animate({'fill': "#000000"}, getTempo(), function() {
                    callbackAnim();
                });
            });
            animations.push(function() {
                var color = "#bfa";
                var style = {stroke: color};
                edge.connection.fg.animate(style, getTempo(), function() {
                    callbackAnim();
                });
            });
        } else {
            animations.push(function() {
                addLog("Odwiedzam: " + id);
                g.nodes[id].shape[0].animate({'fill': "#000000"}, getTempo(), function() {
                    callbackAnim();
                });
            });
        }
    };

    showGraphTab = function() {
        if (active) {
            mode = "drag";
            setMovingMode();
            $("#dragMode").attr('checked', "checked");
            hideAllTabs();
            $("#graphTab").show();
            $("#gtb").css("background-color", "#AEE6AC");
            $("#atb").css("background-color", "#A9EEDA");
            $("#amtb").css("background-color", "#A9EEDA");
        }
    };

    showAlgorithmTab = function() {
        if (active) {
            hideAllTabs();
            $("#algorithmTab").show();
            $("#gtb").css("background-color", "#A9EEDA");
            $("#atb").css("background-color", "#AEE6AC");
            $("#amtb").css("background-color", "#A9EEDA");
            mode = "drag";
            $("#instructions").html("");
            log("");
        }
    };

    showAlgorithmMakerTab = function() {
        if (active) {
            hideAllTabs();
            $("#algorithmMakerTab").show();
            $("#gtb").css("background-color", "#A9EEDA");
            $("#atb").css("background-color", "#A9EEDA");
            $("#amtb").css("background-color", "#AEE6AC");
            $("#instructions").html(algdefiningInstr);
            log("");
        }
    };

    hideAllTabs = function() {
        $("#graphTab").hide();
        $("#algorithmTab").hide();
        $("#algorithmMakerTab").hide();
    };

    bfs = function() {
        var previous = new Array();
        animations.reset();
        for (var id in g.nodes) {
            g.nodes[id].shape[0].animate({'fill': "#ffffff"}, getTempo());
            g.nodes[id].visited = 0;
        }

        var q = [];
        var startId = $("#startId").val();
        g.nodes[startId].visited = 1;
        var id = startId;
        while (id) {
            for (var i in g.nodes[id].edges) {
                var edge = g.nodes[id].edges[i];
                var idSasiada = edge.target.id;
                if (idSasiada == id && !directed) {
                    idSasiada = edge.source.id;
                }
                if (g.nodes[idSasiada].visited === 0) {
                    g.nodes[idSasiada].visited = 1;
                    q.push(idSasiada);
                    previous[idSasiada] = id;
                }
            }

            g.nodes[id].visited = 2;
            // musi byc w funkcji, bo inaczej wszystkie id w animacji
            //  uznaje za ostatnia wartosc
            addAnim(id, previous[id]);
            id = q.shift();
        }
    };

    var c;
    var f;
    var s;
    var t;
    var n;
    flow = function() {
        animations.reset();
        s = $("#startId").val();
        t = $("#finishId").val()
        c = {};
        for (var id in g.nodes) {
            c[id] = {};
            for (var toId in g.nodes) {
                var edge = g.getEdge(id, toId);
                if (edge) {
                    c[id][toId] = edge.weight;
                    setEdgeLabel(edge, "0/" + edge.weight);
                } else {
                    c[id][toId] = 0;
                }
            }
        }
        f = {};
        for (var id in g.nodes) {
            f[id] = {};
            for (var toId in g.nodes) {
                f[id][toId] = 0;
            }
        }
        var path = findPath();
        while (path) {
            increaseFlow(path);
            path = findPath();
        }
    };

    increaseFlow = function(path) {
        animations.push(function() {
            addLog("Znaleziono ścieżkę powiększającą: " + path.toString());
            callbackAnim();
        });

        var min = c[path[0]][path[1]] - f[path[0]][path[1]];
        var i = 0;
        while (i < path.length - 1) {
            var id = path[i];
            var id2 = path[i + 1];
            var cr = c[id][id2] - f[id][id2];
            if (cr < min) {
                min = cr;
            }
            i++;
        }
        i = 0;
        while (i < path.length - 1) {
            var id = path[i];
            var id2 = path[i + 1];
            var edge;
            if (c[id][id2] > 0) {
                edge = g.getEdge(id, id2);
                addAnimu(edge, min);
            } else {
                edge = g.getEdge(id2, id);
                addAnimu(edge, -min);
            }
            f[id][id2] += min;
            f[id2][id] -= min;
            i++;
        }
        addClear();
    };

    findPath = function() {
        var vis = {};
        var parent = {};
        for (var id in g.nodes) {
            vis[id] = 0;
        }
        var q = [];
        vis[s] = 1;
        var id = s;
        var found = false;
        while (!found && id) {
            for (var i in g.nodes[id].edges) {
                var idSasiada = g.nodes[id].edges[i].target.id;
                if (idSasiada != id && c[id][idSasiada] - f[id][idSasiada] > 0) {
                    if (vis[idSasiada] === 0) {
                        vis[idSasiada] = 1;
                        parent[idSasiada] = id;
                        q.push(idSasiada);
                    }
                    if (idSasiada == t) {
                        found = true;
                        break;
                    }
                }
                idSasiada = g.nodes[id].edges[i].source.id;
                if (idSasiada != id && c[id][idSasiada] - f[id][idSasiada] > 0) {
                    if (vis[idSasiada] === 0) {
                        vis[idSasiada] = 1;
                        parent[idSasiada] = id;
                        q.push(idSasiada);
                    }
                    if (idSasiada == t) {
                        found = true;
                        break;
                    }
                }
            }
            vis[id] = 2;
            id = q.shift();
        }
        if (found) {
            var path = new Array();
            path.push(t);
            var x = t;
            while (x != s) {
                x = parent[x];
                path.push(x);
            }
            path.reverse();
            return path;
        }
        return null;
    };

    addAnim = function(id, idOfPrevious) {

        if (idOfPrevious) {
            var edge = g.getEdge(idOfPrevious, id);
            if (!edge) {
                edge = g.getEdge(id, idOfPrevious);
            }
        }

        animations.push(function() {
            addLog("Odwiedzam: " + id);
            if (idOfPrevious) {
                var color = "#f00";
                var style = {stroke: color};
                edge.connection.fg.animate(style, getTempo());
            }
            g.nodes[id].shape[0].animate({'fill': "#000000"}, getTempo(), function() {
                callbackAnim();
            });
        });
        if (idOfPrevious) {
            animations.push(function() {
                var color = "#bfa";
                var style = {stroke: color};
                edge.connection.fg.animate(style, getTempo(), function() {
                    callbackAnim();
                });
            });
        }
    };

    addAnimu = function(edge, min) {
        animations.push(function() {
            addLog("Zwiększam przepływ na krawędzi " + edge.source.id + "-" + edge.target.id + " o " + min);
            var prevLabel = edge.connection.label.attr('text');
            var prevF = parseInt(prevLabel.split("/")[0]);
            var c = prevLabel.split("/")[1];
            var newF = prevF + min;
            var newLabel = newF + "/" + c;
            setEdgeLabel(edge, newLabel);

            var color = "#f00";
            var style = {stroke: color};
            edge.connection.fg.animate(style, getTempo(), function() {
                callbackAnim();
            });
        });
    };

    callbackAnim = function() {
        if (!stepped) {
            animations.next();
        }
    }

    addClear = function() {
        animations.push(function() {
            $("#out").html("przeplyw zwiekszany o: ");
            for (var i in g.edges) {
                var edge = g.edges[i];
                var color = "#bfa";
                var style = {stroke: color};
                edge.connection.fg.animate(style, 1000);
            }
            g.nodes[1].shape[0].animate({'fill': "#000000"}, 1500, function() {
                callbackAnim();
            });
        });
    };

    addLog = function(msg) {
        $("#logs").prepend(msg + "<br/>");
    };

    function CanvasClick(e) {
        if (e.target.nodeName === "svg" && mode === "draw") {
            var i = 1;
            var found = false;
            while (!found) {
                if (!g.nodes[i]) {
                    found = true;
                } else {
                    i++;
                }
            }
            var proposedId = i;
            var newId;
            if ($('#nodeInput').attr('checked') === "checked") {
                newId = prompt("Podaj id wierzchołka:", proposedId);
            } else {
                newId = proposedId;
            }
            if (newId !== null && newId !== "" && !g.nodes[newId]) {
                newId = filterName(newId);
                var node = g.addNode(newId);
                renderer.drawNode(node, e.pageX - $('#canvas').offset().left, e.pageY - $('#canvas').offset().top);
                log("Stworzono wierzchołek o id: " + newId);
            }
        }
    }

    filterName = function(str) {
        if (str == null) {
            return str;
        } else {
            return String(str).replace(/[^a-zA-Z0-9]/g, '');
        }
    };

    filterWeight = function(str) {
        if (str == null) {
            return str;
        } else {
            return String(str).replace(/[^0-9]/g, '');
        }
    };

    newNodeClick = function(e) {
        switch (mode) {
            case "drag":
                this.dx = e.clientX;
                this.dy = e.clientY;
                renderer.isDrag = this;
                this.set && this.set.animate({"fill-opacity": .1}, 200) && this.set.toFront();
                e.preventDefault && e.preventDefault();
                break;
            case "draw":
                var text = this.attr("text");
                var id;
                if (text) {
                    id = text;
                } else {
                    id = this.node.id;
                }

                if (!prev) {
                    prev = id;
                    $("#canvas").mousemove(function(e) {
                        if (mode === "draw" && prev) {
                            drawTempLine(e);
                        }
                    });
                } else {
                    var a = prev;
                    var b = id;
                    prev = undefined;

                    if (a != b) {
                        var proposedWeight = 10;
                        var newWeight;
                        if ($('#edgeInput').attr('checked') === "checked") {
                            newWeight = prompt("Podaj wagę krawędzi:", proposedWeight);
                        } else {
                            newWeight = undefined;
                        }
                        if (newWeight !== null && addEdge(a, b, newWeight)) {
                            var edge = g.getEdge(a, b);
                            renderer.drawEdge(edge);
                            log("Stworzono krawędź między wierzchołkami: " + a + " i " + b);
                        }
                    }
                    hideTempLine();
                    $("#canvas").off('mousemove');
                }
                break;
            case "delete":
                var text = this.attr("text");
                var id;
                if (text) {
                    id = text;
                } else {
                    id = this.node.id;
                }
                g.removeNode(id);
                log("Usunięto wierzchołek o id: " + id);
                break;
        }
    };

    getTempo = function() {
        return 300 + (10 - $("#tempo").val()) * 200;
    };

    var prev;
    var tempLine;

    drawTempLine = function(e) {

        var ax = g.nodes[prev].shape[0].attr('cx');
        var ay = g.nodes[prev].shape[0].attr('cy');
        var bx = e.offsetX;
        var by = e.offsetY;
//                    console.debug(ax, ay, bx, by);
//                    console.debug(e.x);
//bx = e.pageX - $(document).scrollLeft() - $('#canvas').offset().left;
//by = e.pageY - $(document).scrollTop() - $('#canvas').offset().top;
        bx = e.pageX - $('#canvas').offset().left;
        by = e.pageY - $('#canvas').offset().top;
//console.debug( posx );

        if (!tempLine) {
            tempLine = renderer.r.path(getTempLinePath(ax, ay, bx, by));
            tempLine.attr({'stroke-width': 3});
            tempLine.toBack();
        } else {
            tempLine.show();
            tempLine.attr({'path': getTempLinePath(ax, ay, bx, by)});
        }
    };

    hideTempLine = function() {
        if (tempLine) {
            tempLine.hide();
        }
    };

    getTempLinePath = function(ax, ay, bx, by) {
        return "M" + ax + "," + ay + "L" + bx + "," + by;
    };

    setMovingMode = function() {
        $("#instructions").html(movingModeInstructions);
        log("");
        hideTempLine();
        prev = undefined;
    };

    setDrawingMode = function() {
        $("#instructions").html(drawModeInstr);
        log("");
    };

    setRemovingMode = function() {
        $("#instructions").html(removeModeInstr);
        log("");
        hideTempLine();
        prev = undefined;
    };

    var log = function(info) {
        $("#logs").html(info);
    };

    var animations = function() {
        var animationQueue = []
                , obj = {}

        obj.push = function(fn) {
            animationQueue.push(fn)
        }

        obj.next = function() {
            if (animationQueue.length !== 0) {
                animationQueue.shift().call()
            } else {
                setControlsActive();
                stepped = true;
                addLog("---Koniec animacji");
            }
        }

        obj.reset = function() {
            animationQueue = [];
        }


        return obj
    }()

    var directed = true;
    var active = true;
    var stepped = true;

    var g = new Graph();
    addEdge(1, 2, 10);
    addEdge(1, 3, 10);
    addEdge(2, 3, 1);
    addEdge(2, 4, 10);
    addEdge(3, 4, 10);

    var layouter = new Graph.Layout.Spring(g);
    layouter.layout();


    var renderer = new Graph.Renderer.Raphael('canvas', g, 1000, 400);
    renderer.draw();

    setDirected = function() {
        directed = true;
        $('#directed').attr('checked', "checked");
    };

    setUndirected = function() {
        directed = false;
        $('#directed').removeAttr('checked');
    };

    $('#graphLoader').click(function() {
        for (var id in g.nodes) {
            g.removeNode(id);
        }
        var graphId = $('#graphName').val();
        var graphName = $("option[value=" + graphId + "]").text();
        switch (graphId) {
            case "g-1":
                setDirected();
                addEdge(1, 2, 10);
                addEdge(1, 3, 10);
                addEdge(2, 3, 1);
                addEdge(2, 4, 10);
                addEdge(3, 4, 10);
                break;
            case "g-2":
                setUndirected();
                addEdge(1, 2);
                addEdge(1, 3);
                addEdge(1, 4);
                addEdge(1, 5);
                addEdge(1, 6);
                addEdge(2, 7);
                addEdge(3, 8);
                addEdge(4, 9);
                addEdge(5, 10);
                addEdge(6, 11);
                addEdge(7, 12);
                addEdge(8, 13);
                addEdge(9, 14);
                addEdge(10, 15);
                addEdge(11, 16);
                addEdge(15, 17);
                addEdge(16, 17);
                break;
            case "g-3":
                setDirected();
                addEdge(1, 2);
                addEdge(1, 3);
                addEdge(2, 3);
                addEdge(2, 4);
                addEdge(3, 4);
                addEdge(4, 5);
                addEdge(5, 6);
                addEdge(5, 7);
                addEdge(5, 8);
                addEdge(6, 8);
                addEdge(7, 8);
                addEdge(1, 9);
                addEdge(9, 10);
                addEdge(10, 11);
                addEdge(1, 12);
                addEdge(1, 13);
                addEdge(13, 11);
                break;
            case "g-4":
                setDirected();
                break;
            default:
                loadGraph(graphId);
        }
        redraw();
        log("Wczytano graf o nazwie: " + graphName);
    });

    $("#directed").change(function() {

        var confirmed = true;
        if (g.edges.length > 0) {
            confirmed = confirm("Czy na pewno przekonwertować istniejący graf? Konwersja zostanie przeprowadzona w sposób niedeterministyczny.");
        }

        var checked = ($(this).attr('checked') === "checked");
        if (confirmed) {
            if (checked) {
                convertToDirected();
            } else {
                convertToUndirected();
            }
        } else {
            if (checked) {
                $(this).removeAttr('checked');
            } else {
                $(this).attr('checked', "checked");
            }
        }

    });

    convertToDirected = function() {
        directed = true;
        for (var i in g.edges) {
            var edge = g.edges[i];
            edge.style.directed = true;
        }
        redraw();
        log("Skonwertowano na skierowane.");
    };

    convertToUndirected = function() {
        directed = false;
        for (var id in g.nodes) {
            for (var i in g.nodes[id].edges) {
                var edge = g.nodes[id].edges[i];
                edge.style.directed = false;
                var start = edge.source.id;
                var end = edge.target.id;
            }
        }
        redraw();
        log("Skonwertowano na nieskierowane.");
    };

    $("#modeSelect input").change(function() {
        mode = this.value;
        switch (mode) {
            case "drag":
                setMovingMode();
                break;
            case "draw":
                setDrawingMode();
                break;
            case "delete":
                setRemovingMode();
                break;
        }
    });

    $("#redrawer").click(function() {
        if (active) {
            redraw();
        }
    });

    $("#resizer").click(function() {
        if (active) {
            var width = prompt("Podaj szerokość obszaru w pikselach (min 400):", renderer.r.width);
            var height = prompt("Podaj wysokość obszaru w pikselach (min 400):", renderer.r.height);
            width = width || 1000;
            height = height || 400;
            width = width >= 400 ? width : 400;
            height = height >= 400 ? height : 400;
            renderer.setSize(width, height);
            redraw();
        }
    });

    var movingModeInstructions = "Kliknij i przytrzymaj wierzchołek, aby go przenieść<br/><br/>";
    var drawModeInstr = "Kliknij na pustym miejscu, aby dodać nowy wierzchołek.<br/><br/>Kliknij na wierzchołku aby rozpocząć tworzenie krawędzi, a następnie kliknij na innym wierzchołku aby powstała krawędź<br/><br/>";
    var removeModeInstr = "Kliknij na wierzchołku, aby go usunąć.<br/><br/>Kliknij na krawędzi, aby ją usunąć.<br/><br/>";
    var algdefiningInstr = 'Aby uruchomić algorytm, wybierz pozycję "algorytm użytkownika" w zakładce "algorytm"';

    $("#instructions").html(movingModeInstructions);
    $("#canvas").click(CanvasClick);
    showGraphTab();

});